home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
system
/
serial
/
dcon0.000
/
dcon0
/
dcon0.96
/
dcon.c
next >
Wrap
C/C++ Source or Header
|
1996-07-20
|
29KB
|
1,183 lines
/*
* dcon version 0.91 April 1996
*
* Copyright (C) 1989,1996 Daniel Chouinard
*
* Permission to use, copy, and distribute this software and its
* documentation for any purpose without fee is hereby granted,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation.
*
* Permission to modify the software is granted, but not the right to
* distribute the modified code so that only one version of the language
* syntax may be agreed upon.
*
* This software is provided "as is" without express or implied warranty.
*
* See dcon.doc for more information.
*/
/*
*
* Bugs:
*
* getvalue() evaluates from left to right and doesn't respect mathematical
* conventions. ie. 5*3+1 evaluates to 20 because 3+1 is evaluated first and
* then 5 times that. Parenthesis can be used in the mean time. (ie. (5*3)+1)
* 5-3+1, no better, evaluates to 1.
*
*/
#include <stdio.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/types.h>
#include <termio.h>
#include <fcntl.h>
#define MAXGOSUBS 32 /* Max depth */
#define STRINGL 512 /* String lengths. Also, max script line length */
#define MAXPATH 512 /* Max filename length (less or equal to STRINGL) */
#define MAXTOKEN 20 /* Maximum token or label length */
#define BOOL unsigned char
FILE *filep;
unsigned char *script;
int scriptspace;
BOOL ifres;
int lastpc,pc; /* program "counters" */
long resultcode=0; /* result code */
int ignorecase=1; /* no case sensitivity */
BOOL comecho=0; /* echo what's comin' in */
long senddelay=0; /* 0/100th second character delay for sending */
long number; /* For getonearg() returning an long */
long intvars[26]; /* [a-z] integer variables */
char string[STRINGL]; /* For getstring() returns and misc. use (misuse) */
char stringvars[26][STRINGL]; /* $[a-z] string variables (Should be malloced) */
char cspeed[10]; /* Ascii representation of baudrate */
int speed=B2400; /* Set to B110, B150, B300,..., B38400 */
char device[MAXPATH]; /* Comm device. May be "-" */
char token[MAXTOKEN]; /* For gettoken() returns */
char scriptfile[MAXPATH]; /* Script file name */
BOOL verbose=0; /* Log actions */
struct termio cons, stbuf, svbuf; /* termios: svbuf=before, stbuf=while */
int comfd= -1; /* Communication file descriptor. May be 0 */
char msg[STRINGL]; /* Massage messages here */
int preturn,returns[MAXGOSUBS];
int clocal=0;
int parity=0, bits=CS8, stopbits=0;
unsigned long hstart,hset;
BOOL lastcharnl=1; /* Indicate that last char printed from getonebyte
was a nl, so no new one is needed */
/* Returns hundreds of seconds */
long htime() {
struct timeval timenow;
gettimeofday(&timenow,NULL);
return(100L*(timenow.tv_sec-hstart)+(timenow.tv_usec)/10000L-hset);
}
/* I use select() 'cause CX/UX 6.2 doesn't have usleep().
On Linux, usleep() uses select() anyway.
*/
void dormir(unsigned long microsecs) {
struct timeval timeout;
timeout.tv_sec=microsecs/1000000L;
timeout.tv_usec=microsecs-(timeout.tv_sec*1000000L);
select(1,(fd_set *)0,(fd_set *)0,(fd_set *)0,&timeout);
}
/* Tests for ENTER key */
void dotestkey() {
fd_set fds[2];
struct timeval timeout;
timeout.tv_sec=0L;
timeout.tv_usec=10000L;
FD_ZERO(fds);
FD_SET(0,fds); /* Prepare to select() from stdin */
resultcode=select(1,fds,0,0,&timeout);
if(resultcode) getchar();
}
/* Exit after resetting terminal settings */
void ext(long xtc) {
ioctl(1, TCSETA, &cons);
exit(xtc);
}
/* Log message if verbose is on */
void vmsg(char *text) {
time_t t;
char *ct;
if(verbose) {
if(lastcharnl==0) {
fprintf(stderr,"\n");
lastcharnl=1;
}
t=time(0);
ct=ctime(&t);
fprintf(stderr,"dcon %c%c:%c%c:%c%c -> %s\r\n",
ct[11],ct[12],ct[14],ct[15],ct[17],ct[18],
text);
}
}
/* Skip to next statement */
void skipline() {
while(script[pc]!='\n' && script[pc]!=0) pc++;
if(script[pc]) pc++;
}
void printwhere() {
int a,b,c;
sprintf(msg,"@%04d ",pc);
a=pc;
skipline();
b=pc-1;
pc=a;
c=strlen(msg);
for(;a<b;a++) msg[c++]=script[a];
msg[c]=0;
vmsg(msg);
}
/* Write a null-terminated string to communication device */
void writecom(char *text) {
int res,a;
char ch;
for(a=0;a<strlen(text);a++) {
ch=text[a];
res=write(comfd,&ch,1);
if(senddelay) dormir(senddelay);
if(res!=1) {
fprintf(stderr,"Could not write to device!\n");
ext(1);
}
}
}
/* Gets a single byte from comm. device. Return -1 if none avail. */
int getonebyte() {
int res;
char ch;
res=0;
res=read(comfd,&ch,1);
if(res==1) {
if(comecho) {
if(ch=='\n') lastcharnl=1;
else {
if(ch!='\r') lastcharnl=0;
}
fputc(ch,stderr);
}
return(ch);
}
dormir(100000); /* No char received, wait 1/10th sec. */
return(-1);
}
/* Report script errors and quit */
void serror(char *text) {
int a,line;
if(verbose==0) {
verbose=1;
a=pc;
pc=lastpc;
printwhere();
pc=a;
}
strcpy(msg,"----> ");
for(a=6;a<STRINGL;a++) msg[a]=' ';
for(a=0;a<pc-lastpc;a++) {
if(script[a+lastpc]=='\t') msg[a+8]='\t';
}
a+=6;
msg[a++]='^';
msg[a]=0;
vmsg(msg);
a=0; line=1;
while(a<pc) {
if(script[a++]=='\n') {
if(a<pc) line++;
}
}
sprintf(msg,"Error @%d, line %d, %s.\n",pc,line,text);
vmsg(msg);
ext(1);
}
void skipspaces() {
while(script[pc]==' ' || script[pc]=='\t' ) pc++;
}
void getopen() {
skipspaces();
if(script[pc++]!='(') serror("Function requires open parenthesis");
}
void getclose() {
skipspaces();
if(script[pc++]!=')') serror("Function requires close parenthesis");
}
/* Parse script[pc] to get next statement. Resolve comments and labels... */
int gettoken() {
int tokenp=0;
skipspaces();
if(script[pc]=='=' || script[pc]=='<' || script[pc]=='>' || script[pc]=='!') {
if(script[pc]=='!') {
if(script[pc+1]!='=') serror("Invalid token. Use '!='");
strcpy(token,"!=");
pc+=2;
return(0);
}
token[0]=script[pc++];
token[1]=0;
return(0);
}
if(script[pc]=='#') {
strcpy(token,"rem");
pc++;
return(0);
}
if(script[pc]=='/' && script[pc+1]=='/') {
strcpy(token,"rem");
pc+=2;
return(0);
}
if(script[pc]==':') {
strcpy(token,"label");
pc++;
return(0);
}
while(script[pc]!=' ' && script[pc]!='\n' &&
script[pc]!='\t' && script[pc]!='(') {
token[tokenp]=script[pc++];
if(tokenp++==MAXTOKEN-1) serror("Token too long");
}
token[tokenp]=0;
skipspaces();
if(strcmp(token,"then")==0) gettoken(); /* Ignore then for if */
return(0);
}
/* shitfaced recursive value parser. must write better one */
long getvalue() {
unsigned long p=0;
int goone=1;
unsigned char index;
skipspaces();
if(script[pc]=='(') {
pc++;
p=getvalue();
getclose();
}
else if(script[pc]==')') {
return(p);
}
else if(script[pc]>='a' && script[pc]<='z' && script[pc+1]>='a' &&
script[pc+1]<='z') {
gettoken();
getopen();
if(strcmp(token,"len")==0) {
getstring();
p=strlen(string);
}
else if(strcmp(token,"htime")==0) {
p=htime();
}
else if(strcmp(token,"time")==0) {
p=time(0);
}
else if(strcmp(token,"pid")==0) {
p=getpid();
}
else if(strcmp(token,"ppid")==0) {
p=getppid();
}
else if(strcmp(token,"baud")==0) {
p=atol(cspeed);
}
else if(strcmp(token,"val")==0 || strcmp(token,"atol")==0) {
getstring();
p=atol(string);
}
else serror("Unknown Integer function");
getclose();
}
if(script[pc]=='%') {
pc++;
skipspaces();
p=resultcode;
}
while(goone) {
if(script[pc]=='+') {
pc++;
p+=getvalue();
}
else if(script[pc]=='-') {
pc++;
p-=getvalue();
}
else if(script[pc]=='^') {
pc++;
p^=getvalue();
}
else if(script[pc]=='&') {
pc++;
p&=getvalue();
}
else if(script[pc]=='|') {
pc++;
p|=getvalue();
}
else if(script[pc]=='*') {
pc++;
p*=getvalue();
}
else if(script[pc]=='/') {
pc++;
p/=getvalue();
}
else if((script[pc]>='a' && script[pc]<='z') ) {
index=script[pc++];
p=intvars[index-'a'];
}
else if(script[pc]>='0' && script[pc]<='9') {
p=p*10+script[pc++]-'0';
}
else {
goone=0;
}
}
return(p);
}
void getcomma() {
skipspaces();
if(script[pc++]!=',') serror("Comma expected");
}
/* Parse a string from script[pc] */
getstring() {
FILE *fp;
time_t t;
int a,b,c,p=0;
unsigned char index,ch,match;
string[0]=0;
skipspaces();
while(script[pc]!=' ' && script[pc]!='\t' && script[pc]!='\n' && script[pc]!=',' && script[pc]!=')' && script[pc]!='=' && script[pc]!='<' && script[pc]!='>' && script[pc]!='!' ) {
if(script[pc]=='+') pc++;
skipspaces();
if(script[pc]=='$' && script[pc+1]>='a' && script[pc+1]<='z' &&
script[pc+2]>='a' && script[pc+2]<='z') {
pc++;
gettoken();
getopen();
if(strcmp(token,"time")==0) {
t=time(0);
strcat(string,ctime(&t));
string[strlen(string)-1]=0;
}
else if(strcmp(token,"rpipe")==0) {
char toto[STRINGL];
strcpy(toto,string);
getstring();
if((fp=popen(string,"r"))==NULL) serror("Could not popen!");
fgets(string,STRINGL-1,fp);
string[strlen(string)-1]=0;
pclose(fp);
strcat(toto,string);
strcpy(string,toto);
}
else if(strcmp(token,"env")==0) {
getstring();
if(getenv(string)) strcpy(string,(char *)getenv(string));
else string[0]=0;
}
else if(strcmp(token,"hms")==0) {
long sec,min,hour;
sec=getvalue();
min=sec/60L;
sec-=min*60L;
hour=min/60L;
min-=hour*60L;
sprintf(string,"%s%02ld:%02ld:%02ld",string,hour,min,sec);
}
else if(strcmp(token,"dev")==0) {
strcat(string,device);
}
else if(strcmp(token,"cwd")==0) {
getcwd(string,STRINGL);
}
else if(strcmp(token,"baud")==0) {
strcat(string,cspeed);
}
else if(strcmp(token,"str")==0 || strcmp(token,"ltoa")==0) {
sprintf(string,"%ld",getvalue());
}
else if(strcmp(token,"mid")==0) {
char toto[STRINGL];
strcpy(toto,string);
getstring();
getcomma();
a=getvalue();
getcomma();
b=getvalue();
if(a>strlen(string)) serror("String is shorter than second argument");
c=strlen(toto);
while(b!=0 && string[a]!=0) {
toto[c++]=string[a++];
b--;
}
toto[c]=0;
strcpy(string,toto);
}
else serror("Invalid string funtion");
getclose();
}
else if(script[pc]=='$') {
index=script[++pc];
if(index<'a' || index>'z') serror("String variables are [a-z]");
strcat(string,stringvars[index-'a']);
pc++;
}
else if(script[pc]=='"' || script[pc]=='\'') {
match=script[pc++];
while(script[pc]!=match) {
ch=script[pc++];
if(ch==0) serror("Umatched quote.");
if(ch=='\\') {
if(script[pc]<='7' && script[pc]>='0' &&
script[pc+1]<='7' && script[pc+1]>='0' &&
script[pc+2]<='7' && script[pc+2]>='0' ) {
index=0;
for(p=0;p<3;p++) {
index=8*index+script[pc++]-'0';
}
pc--;
ch=index;
}
else if(script[pc]=='t') ch=9;
else if(script[pc]=='r') ch=13;
else if(script[pc]=='n') ch=10;
else if(script[pc]=='b') ch=8;
else if(script[pc]=='f') ch=12;
else if(script[pc]=='"') ch='"';
else if(script[pc]=='^') ch='^';
else if(script[pc]=='\'') ch='\'';
else if(script[pc]=='\\') ch=script[pc];
else serror("Malformed escaped character");
pc++;
}
else if(ch=='^') {
ch=script[pc];
if(ch!='^' && ch!='"' && ch!='\'' && ch!='\\' ) {
ch=ch&31; /* Control char */
}
pc++;
}
p=strlen(string);
string[p++]=ch;
string[p]=0;
}
pc++; /* Space over quote */
}
else {
p=strlen(string);
string[p++]=script[pc++];
string[p]=0;
}
}
}
/* Get a value, multiply by a hundred (for time values) */
unsigned long getdvalue() {
float f;
getstring();
skipspaces();
sscanf(string,"%f",&f);
f+=0.00001; /* Rounding errors */
return(100.0*f);
}
void dolet() {
unsigned char index,svar=0;
if(script[pc]=='$') {
svar=1;
pc++;
}
index=script[pc++];
if(index>'z' || index<'a') serror("Bad variable name");
index-='a';
skipspaces();
gettoken();
if(strcmp(token,"=")!=0) serror("Bad LET assignment, '=' missing");
skipspaces();
if(svar) {
getstring();
strcpy(stringvars[index],string);
}
else {
intvars[index]=getvalue();
}
}
/* See documentation for doXXX() functions */
int dowaitquiet() {
unsigned long timeout,timequiet,quiet,now;
int c,quit;
timeout=htime()+getdvalue();
quiet=getdvalue();
timequiet=htime()+quiet;
quit=1;
while(quit==1) {
now=htime();
c=getonebyte();
if(c!= -1) timequiet=now+quiet;
if(now>=timequiet) quit=0;
if(now>=timeout) quit=255;
}
return(quit);
}
int dowaitfor() {
char strings[20][80];
char buffer[128];
unsigned long timeout;
int a,b,c;
b=0;
buffer[127]=0;
skipspaces();
timeout=htime()+getdvalue();
while(script[pc]==',' || script[pc]=='$' || script[pc]=='"' ||
script[pc]=='\'' ) {
if(script[pc]==',') pc++;
getstring();
skipspaces();
strcpy(strings[b],string);
if(ignorecase) {
for(a=0;a<strlen(strings[b]);a++) {
if(strings[b][a]>='A' && strings[b][a]<='Z') {
strings[b][a]=strings[b][a]-'A'+'a';
}
}
}
b++;
}
strings[b][0]=0;
while(htime()<timeout) {
c=getonebyte();
if(c!= -1) {
if(ignorecase) {
if(c>='A' && c<='Z') c=c-'A'+'a';
}
for(a=0;a<126;a++) buffer[a]=buffer[a+1];
buffer[126]=c;
b=0;
while(strings[b][0]) {
c=strlen(strings[b]);
a=c-1;
while(a>=0 && strings[b][a]==buffer[127-c+a]) a--;
if(a<0) return(b);
b++;
}
}
}
return(-1);
}
/* Parse script for "on" or "off" wich are tokens, not strings */
BOOL getonoroff() {
gettoken();
if(strcmp(token,"on")==0) return(1);
if(strcmp(token,"off")==0) return(0);
serror("Bad value (should be on or off)");
}
void setcom() {
stbuf.c_cflag &= ~(CBAUD | CSIZE | CSTOPB | CLOCAL | PARENB);
stbuf.c_cflag |= (speed | bits | CREAD | clocal | parity | stopbits );
if (ioctl(comfd, TCSETA, &stbuf) < 0) {
serror("Can't ioctl set device");
ext(1);
}
}
void doset() {
struct termio console;
int a,b;
gettoken();
if(strcmp(token,"echo")==0) {
a=0;
if(getonoroff()) a=ECHO|ECHOE;
if(ioctl(0, TCGETA, &console)<0) {
fprintf(stderr,"Can't ioctl FD zero!\n");
ext(1);
}
console.c_lflag &= ~(ECHO | ECHOE);
console.c_lflag |= a;
ioctl(0, TCSETA, &console);
}
else if(strcmp(token,"senddelay")==0) {
senddelay=10000L*getdvalue();
}
else if(strcmp(token,"clocal")==0) {
clocal=0;
if(getonoroff()) clocal=CLOCAL;
setcom();
}
else if(strcmp(token,"umask")==0) {
getstring();
sscanf(string,"%o",&a);
umask(0777-a);
}
else if(strcmp(token,"verbose")==0) {
verbose=getonoroff();
}
else if(strcmp(token,"comecho")==0) {
comecho=getonoroff();
}
else if(strcmp(token,"ignorecase")==0) {
ignorecase=getonoroff();
}
else if(strcmp(token,"com")==0) {
getstring();
a=0;
b=0;
while(string[b]>='0' && string[b]<='9') {
a=10*a+string[b++]-'0';
}
if(string[b]) {
if(string[b]>='A' && string[b]<='Z') string[b]=string[b]-'A'+'a';
switch(string[b]) {
case 'n': parity=0; break;
case 'e': parity=PARENB; break;
case 'o': parity=PARENB|PARODD; break;
default : serror("Parity can only ben E, N, or O");
}
b++;
if(string[b]) {
switch(string[b]) {
case '5' : bits=CS5; break;
case '6' : bits=CS6; break;
case '7' : bits=CS7; break;
case '8' : bits=CS8; break;
default : serror("Bits can only be 5, 6, 7, or 8");
}
b++;
if(string[b]) {
switch(string[b]) {
case '1': stopbits=0; break;
case '2': stopbits=CSTOPB; break;
default : serror("Stop bits can only be 1 or 2");
}
}
}
}
sprintf(cspeed,"%d",a);
switch(a) {
case 110: speed = B110;break;
case 150: speed = B150;break;
case 300: speed = B300;break;
case 1200: speed = B1200;break;
case 2400: speed = B2400;break;
case 4800: speed = B4800;break;
case 9600: speed = B9600;break;
case 19200: speed = B19200;break;
case 38400: speed = B38400;break;
default: serror("Invalid baudrate");
}
setcom();
}
}
void dogoto() {
int gonethruonce=0,quitsearch=0;
char label[80];
getstring();
strcpy(label,string);
skipline();
while(quitsearch==0) {
if(script[pc]==0) {
if(gonethruonce==0) {
gonethruonce=1;
pc=0;
}
else {
sprintf(msg,"Label \"%s\" not found",label);
serror(msg);
}
}
gettoken();
if(strcmp(token,"label")==0) {
getstring();
if(strcmp(string,label)==0) quitsearch=1;
}
if(quitsearch==0) skipline();
}
}
void dogosub() {
int a;
if(preturn==MAXGOSUBS) serror("Reached maximum GOSUB depth");
a=pc;
while(script[a]!='\n') a++;
returns[preturn++]=a;
dogoto();
}
void doreturn() {
if(preturn==0) serror("RETURN without gosub");
pc=returns[--preturn];
}
/* Gets arguments and returns 0 for a string, 1 for an int. Used with if */
unsigned char getonearg() {
if(script[pc]=='"' || script[pc]=='\'' || script[pc]=='$' ) {
getstring();
return(0);
}
else {
number=getvalue();
return(1);
}
}
void doif() {
char stringarg[STRINGL];
char tokencopy[MAXTOKEN];
int intarg;
skipspaces();
ifres=0;
if(getonearg()) {
intarg=number;
gettoken();
skipspaces();
if(getonearg()!=1) serror("Comparison mis-match");
if(strcmp(token,"<")==0) {
if(intarg<number) ifres=1;
}
else if(strcmp(token,"=")==0) {
if(intarg==number) ifres=1;
}
else if(strcmp(token,">")==0) {
if(intarg>number) ifres=1;
}
else if(strcmp(token,"!=")==0) {
if(intarg!=number) ifres=1;
}
}
else {
strcpy(stringarg,string);
gettoken();
strcpy(tokencopy,token);
skipspaces();
if(getonearg()!=0) serror("Comparison mis-match");
if(strcmp(tokencopy,"<")==0) {
if(strcmp(stringarg,string)<0) ifres=1;
}
else if(strcmp(tokencopy,"=")==0) {
if(strcmp(stringarg,string)==0) ifres=1;
}
else if(strcmp(tokencopy,">")==0) {
if(strcmp(stringarg,string)>0) ifres=1;
}
else if(strcmp(tokencopy,"!=")==0) {
if(strcmp(stringarg,string)!=0) ifres=1;
}
}
if(!ifres) skipline();
}
/* Parse script to find integer variable index (ie.: a=0, z=25) */
int getintindex() {
int index;
skipspaces();
if(script[pc]=='$') serror("Requires an integer variable");
index=script[pc++];
if(index>'z' || index<'a') serror("Malformed variable name");
return(index-'a');
}
/* Parse script to find string variable index (ie.: $a=0, $z=25) */
int getstringindex() {
int index;
skipspaces();
if(script[pc++]!='$') serror("Requires a string variable");
index=script[pc++];
if(index>'z' || index<'a') serror("Malformed variable name");
return(index-'a');
}
void doget() {
char terminators[STRINGL];
int a,b,c,index;
int goahead=1;
unsigned long timeout;
timeout=htime()+getdvalue();
getstring();
strcpy(terminators,string);
index=getstringindex();
string[0]=0;
b=0;
resultcode=0;
while(goahead && htime()<timeout) {
c=getonebyte();
if(c!= -1) {
for(a=0;a<strlen(terminators);a++) {
if(c==terminators[a]) goahead=0;
}
if(goahead==0 && b==0) goahead=1; /* Ignore terminators if nothing yet */
else if(goahead) {
string[b++]=c;
string[b]=0;
}
}
}
if(goahead) resultcode= -1;
strcpy(stringvars[index],string);
}
void doinc() {
intvars[getintindex()]++;
}
void dodec() {
intvars[getintindex()]--;
}
void doinput() {
gets(stringvars[getstringindex()]);
}
void doprint(int channel) {
skipspaces();
msg[0]=0;
while(script[pc]!=' ' && script[pc]!='\t' && script[pc]!='\n') {
if(script[pc]==',') pc++;
else {
if(script[pc]=='"' || script[pc]=='\'' || script[pc]=='$' ) {
getstring();
strcat(msg,string);
}
else {
sprintf(string,"%ld",getvalue());
strcat(msg,string);
}
}
}
switch(channel) {
case 1: printf("%s",msg); fflush(stdout); break;
case 2: fputs(msg,stderr); break;
case 3: vmsg(msg); break;
case 4:
if(filep==NULL) serror("File not opened");
fputs(msg,filep);
break;
}
}
void doclose() {
gettoken();
if(strcmp(token,"hardcom")==0) {
if(comfd== -1) serror("Com device not open");
vmsg("Closing device");
if (ioctl(comfd, TCSETA, &svbuf) < 0) {
fprintf(stderr,"Can't ioctl set device %s.\n",device);
ext(1);
}
close(comfd);
comfd= -1;
}
else if(strcmp(token,"com")==0) {
if(comfd== -1) serror("Com device not open");
vmsg("Closing com fd");
close(comfd);
comfd= -1;
}
else if(strcmp(token,"file")==0) {
if(filep==NULL) serror("Log file not open");
fclose(filep);
filep=NULL;
}
}
void doopen() {
gettoken();
if(strcmp(token,"com")==0) {
if(comfd!= -1) serror("Com device already open");
getstring();
strcpy(device,string);
if(strcmp(device,"-")) {
if ((comfd = open(device, O_RDWR|O_EXCL|O_NDELAY)) <0) {
fprintf(stderr,"Can't open device %s.\n",device);
ext(1);
}
}
else comfd=0;
if (ioctl (comfd, TCGETA, &svbuf) < 0) {
fprintf(stderr,"Can't ioctl get device %s.\n",device);
ext(1);
}
ioctl(comfd, TCGETA, &stbuf);
stbuf.c_iflag &= ~(IGNCR | ICRNL | IUCLC | INPCK | IXON | IXANY | IGNPAR );
stbuf.c_oflag &= ~(OPOST | OLCUC | OCRNL | ONLCR | ONLRET);
stbuf.c_lflag &= ~(ICANON | XCASE | ECHO | ECHOE | ECHONL);
stbuf.c_cc[VEOF] = 1;
setcom();
dormir(200000); /* Wait a bit (DTR raise) */
sprintf(msg,"Opened %s as FD %d baudrate:%d",device,comfd,atoi(cspeed));
vmsg(msg);
}
else if (strcmp(token,"file")==0) {
if(filep!=NULL) serror("File already open");
getstring();
if((filep=fopen(string,"a"))==NULL) serror("Could not open file");
}
else serror("OPEN only takes com or file argument");
}
int doscript() {
int a,b,c;
int exitcode=0;
char line[STRINGL];
pc=0;
while(script[pc]) {
if(script[pc]=='\n') pc++;
lastpc=pc;
skipspaces();
if(verbose) printwhere();
if(gettoken()) serror("Could not gettoken()");
skipspaces();
if(strcmp(token,"rem")==0) {
skipline();
}
else if (strcmp(token,"label")==0) {
getstring(); /* Get rid of keyword */
}
else if(strcmp(token,"open")==0) {
doopen();
}
else if(strcmp(token,"close")==0) {
doclose();
}
else if(strcmp(token,"exec")==0) {
getstring();
strcpy(msg,"exec ");
strcat(msg,string); /* Let sh do all the command line work! */
execl("/bin/sh","sh","-c",msg,(char *)0);
serror("Could not execl!");
}
else if(strcmp(token,"exit")==0) {
ext(getvalue());
}
else if(strcmp(token,"testkey")==0) {
dotestkey();
}
else if(strcmp(token,"kill")==0) {
a=getvalue();
resultcode=kill(getvalue(),a);
}
else if(strcmp(token,"fork")==0) {
resultcode=fork();
}
else if(strcmp(token,"hset")==0) {
hset=0;
hstart=time(0);
hset=htime()-getvalue();
}
else if(strcmp(token,"cd")==0) {
getstring();
resultcode=chdir(string);
}
else if(strcmp(token,"putenv")==0) {
getstring();
strcpy(line,string);
resultcode=putenv(line); /* putenv can't read from global string[] */
}
else if(strcmp(token,"wait")==0) {
resultcode=wait(0);
}
else if(strcmp(token,"system")==0) {
getstring();
system(string);
}
else if(strcmp(token,"input")==0) {
doinput();
}
else if(strcmp(token,"get")==0) {
doget();
}
else if(strcmp(token,"print")==0) {
doprint(1);
}
else if(strcmp(token,"eprint")==0) {
doprint(2);
}
else if(strcmp(token,"lprint")==0) {
doprint(3);
}
else if(strcmp(token,"fprint")==0) {
doprint(4);
}
else if(strcmp(token,"if")==0) {
doif();
}
else if(strcmp(token,"else")==0) {
if(ifres) skipline();
}
else if(strcmp(token,"gosub")==0) {
dogosub();
}
else if(strcmp(token,"return")==0) {
doreturn();
}
else if(strcmp(token,"goto")==0) {
dogoto();
}
else if(strcmp(token,"waitfor")==0) {
resultcode=dowaitfor();
}
else if(strcmp(token,"waitquiet")==0) {
resultcode=dowaitquiet();
}
else if(strcmp(token,"set")==0) {
doset();
}
else if(strcmp(token,"dec")==0) {
dodec();
}
else if(strcmp(token,"inc")==0) {
doinc();
}
else if(strcmp(token,"let")==0) {
dolet();
}
else if(strcmp(token,"send")==0) {
getstring();
writecom(string);
}
else if(strcmp(token,"sleep")==0) {
a=getdvalue();
if(a<10000) dormir(10000L*a);
else sleep(a/100); /* I guess it's the same. Oh well, past 10secs,
use sleep instead. */
}
else serror("What's that, governor?");
skipspaces();
while(script[pc]=='\n') pc++;
}
return(exitcode);
}
int main(int argc,char *argv[]) {
int a,b,i,len;
int speed;
unsigned char ch;
unsigned char terminator='\n';
unsigned char line[STRINGL];
FILE *fp;
hstart=time(0);
hset=htime();
preturn=0;
filep=NULL;
scriptspace=4096;
ioctl(1, TCGETA, &cons);
if((script=(char *)malloc(scriptspace))==NULL) {
fprintf(stderr,"Could not malloc()!\n");
ext(1);
}
for(a=0;a<26;a++) {
intvars[a]=0;
stringvars[a][0]=0;
}
strcpy(cspeed,"2400");
scriptfile[0]=0;
for(a = 1; a < argc; a++) {
if(strcmp(argv[a],"-b")==0) strcpy(cspeed,argv[++a]);
else if(strcmp(argv[a],"-t")==0) {
terminator=argv[++a][0];
sprintf(msg,"Alternate line terminator set to \"%c\"",terminator);
vmsg(msg);
}
else if(strcmp(argv[a],"-d")==0) strcpy(device,argv[++a]);
else if(strcmp(argv[a],"-e")==0) comecho=1;
else if(strcmp(argv[a],"-v")==0) verbose=1;
else if(strcmp(argv[a],"-s")==0) {
scriptspace=strlen(argv[++a])+1;
if((script=(char *)realloc(script,scriptspace))==0) {
fprintf(stderr,"Could not malloc()!\n");
ext(1);
}
strcpy(script,argv[a]);
for(a=0;a<scriptspace;a++) {
if(script[a]==terminator) script[a]='\n';
}
}
else {
strcpy(scriptfile,argv[a]);
a=argc;
}
}
if(scriptfile[0]) {
if((fp=fopen(scriptfile,"r"))==NULL) {
fprintf(stderr,"Could not open scriptfile \"%s\".\n",scriptfile);
ext(1);
}
i=strlen(script);
while((fgets(line,STRINGL-1,fp))!=NULL) {
b=strlen(line);
if((scriptspace-i)<STRINGL) {
scriptspace+=STRINGL+STRINGL;
if((script=(char *)realloc(script,scriptspace))==NULL) {
fprintf(stderr,"Could not realloc()!\n");
ext(1);
}
}
for(a=0;a<b;a++) {
script[i]=line[a];
if(script[i]==terminator) script[i]='\n';
i++;
}
}
script[i]=0;
fclose(fp);
}
if(script[0]) {
i=strlen(script)-1;
while((script[i]=='\n' || script[i]==' ' || script[i]=='\t') && i!=0) i--;
script[++i]='\n';
script[++i]=0;
}
if(verbose) {
fprintf(stderr,"argc:%d\n",argc);
for(a=0;a<argc;a++) {
fprintf(stderr,"argv[%d]=%s\n",a,argv[a]);
}
fprintf(stderr,"dcon ---Script---\n");
a=0; b=0; ch='\n';
i=strlen(script);
while(a<scriptspace) {
if(ch=='\n' && script[a]!=0) {
fprintf(stderr,"%4d ",++b);
}
ch=script[a++];
fputc(ch,stderr);
}
fprintf(stderr,"dcon ---End of script---\n");
}
if(script[0]==0) {
fprintf(stderr,"No script!\n");
ext(1);
}
a=doscript();
dormir(200000);
if(comfd!= -1) close(comfd);
sprintf(msg,"Exit with code %d.\n",a);
vmsg(msg);
ext(a);
}